package me.stone.stanimeclient.page.search

import android.text.Editable
import android.view.KeyEvent
import android.view.MenuItem
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import me.stone.stanimeclient.R
import me.stone.stanimeclient.core.common.utils.WhileViewSubscribed
import me.stone.stanimeclient.core.data.domain.data.SearchFanDataListRepository
import me.stone.stanimeclient.core.data.repository.SearchHistoryRepository
import timber.log.Timber
import javax.inject.Inject

interface IDoQueryEvent {
    fun doQuery(query: String)
}

interface IDoDeleteSuggestionEvent {
    fun doDelete(suggestion: String)
}

interface IClearSearchHistoryEvent {
    fun doClearHistory()
}

@HiltViewModel
class SearchViewModel @Inject constructor(
    private val repository: SearchFanDataListRepository,
    private val searchHistoryRepository: SearchHistoryRepository,
) : ViewModel(), IDoQueryEvent, IDoDeleteSuggestionEvent, IClearSearchHistoryEvent {

    // 提交的搜索关键词
    private val _query = MutableStateFlow("")

    // 用户输入的关键词（不做提交操作）
    private var _inputQuery = MutableStateFlow("")

    private val _closeSuggestionSign = MutableSharedFlow<Unit>()

    private var _ignoreChangedSign: Boolean = false

    private val _safeQueryHint: String
        get() = (_inputQuery.value.takeIf { it.isNotBlank() } ?: queryHint).let {
            // API 仅支持查询8个字符
            it.substring(0, it.length.coerceAtMost(8))
        }

    var queryHint: String = ""

    var lockEditorChangedListener: Boolean = false

    val queryContent: StateFlow<String> = _query

    val inputContent: StateFlow<String> = _inputQuery

    @OptIn(ExperimentalCoroutinesApi::class)
    val resultData = _query
        .filter { it.isNotBlank() }
        .flatMapLatest {
            _closeSuggestionSign.emit(Unit)
            Pager(PagingConfig(12)) {
                SearchPagingSource(it, repository)
            }.flow
        }.cachedIn(viewModelScope)

    @OptIn(ExperimentalCoroutinesApi::class)
    val resultInfo = _query
        .filter { it.isNotBlank() }
        .mapLatest {
            try {
                val repo = repository.searchFanDataList(it)
                if (repo.code != 200) {
                    repo.message + "【Tips: 搜索内容不能包含特殊符号】"
                } else {
                    _ignoreChangedSign = true
                    searchHistoryRepository.insertHistory(it)
                    "找到 ${repo.data?.totalCount ?: 0} 部番剧 · $it"
                }
            } catch (e: Exception) {
                "搜索异常：$e"
            }
        }
        .stateIn(viewModelScope, WhileViewSubscribed, "")

    val closeSuggestionSign = _closeSuggestionSign
        .shareIn(viewModelScope, SharingStarted.Eagerly)

    @OptIn(ExperimentalCoroutinesApi::class)
    val suggestions = _inputQuery
        /*.filter {
            val count = if (it.isBlank()) {
                searchHistoryRepository.listCount()
            } else {
                searchHistoryRepository.matchCount(it)
            }
            if (count == 0) { _closeSuggestionSign.emit(Unit) }
            count > 0
        }*/
        .flatMapLatest {
            _ignoreChangedSign = false
            Pager(PagingConfig(12)) {
                if (it.isNotBlank()) {
                    searchHistoryRepository.match(it)
                } else {
                    searchHistoryRepository.listAll()
                }
            }.flow
        }
        .cachedIn(viewModelScope)
        .filter {
            if (_ignoreChangedSign) {
                _ignoreChangedSign = false
                return@filter false
            }
            return@filter true
        }

    fun afterQueryTextChanged(s: Editable) {
        if (lockEditorChangedListener) return
        viewModelScope.launch {
            _inputQuery.emit(s.toString())
        }
    }

    fun onMenuItemClick(item: MenuItem): Boolean {
        if (item.itemId == R.id.search) {
            doQuery(_safeQueryHint)
            return true
        }
        return false
    }

    fun onQueryEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
        if (actionId == EditorInfo.IME_ACTION_SEARCH) {
            doQuery(_safeQueryHint)
            return true
        }
        Timber.d("on action -> $actionId, $event, $v")
        return false
    }

    override fun doQuery(query: String) {
        val safeQuery = query.let {
            if (it.length <= 8) { return@let it }
            return@let it.substring(0, 8)
        }
        _inputQuery.value = safeQuery
        viewModelScope.launch {
            _query.emit(safeQuery)
        }
    }

    override fun doDelete(suggestion: String) {
        viewModelScope.launch {
            searchHistoryRepository.deleteHistory(suggestion)
            // 刷新列表
            _inputQuery.emit(_inputQuery.value)
        }
    }

    override fun doClearHistory() {
        viewModelScope.launch {
            searchHistoryRepository.clearData()
        }
    }

}